﻿namespace Pottery.Module.Store.Models
{
    using System;
    using System.Data.SqlTypes;
    using System.Runtime.Serialization;
    using Model.Infrastructure;
    using Pottery.Module.Infrastructure.Models;

    [DataContract]
    public class PartnerCard : IValidatable, IAssignable, INullable, IEquatable<PartnerCard>
    {
        #region Constructors

        /// <summary>
        /// Initializes new PartnerCard with default params.
        /// </summary>
        public PartnerCard() { }

        /// <summary>
        /// Initializes new PartnerCard with params. 
        /// </summary>
        /// <param name="id">Card id</param>
        /// <param name="customer">Card holder</param>
        public PartnerCard(string id, User customer)
        {
            m_CardID = id;
            m_CardHolder = customer;
        }

        #endregion

        #region Properties

        /// <summary>
        /// ID.
        /// </summary>
        [DataMember(Order = 1)]
        public string CardID
        {
            get { return m_CardID; }
            set
            {
                if (!IsNull)
                    m_CardID = value;
            }
        }

        /// <summary>
        /// Card holder.
        /// </summary>
        [DataMember(Order = 2)]
        public User CardHolder
        {
            get { return m_CardHolder; }
            set
            {
                if (!IsNull)
                    m_CardHolder = value;
            }
        }

        #endregion

        #region IAssignable implementation
        /// <summary>
        /// Copy data from current object to object in param.
        /// </summary>
        /// <param name="obj">object to change </param>
        public void AssignTo(object obj)
        {
            if (IsNull)
                throw new InvalidOperationException();

            if (obj == null)
                throw new ArgumentNullException();

            if (obj is PartnerCard)
            {
                PartnerCard card = obj as PartnerCard;
                card.m_CardID = m_CardID;
                card.m_CardHolder = m_CardHolder;

                card.m_Null = false;

                return;
            }

            throw new NotSupportedException("Not supported type!");
        }
        #endregion

        #region IValidate implementation

        public bool Validate()
        {
            if (m_CardID.Length != ModelConstants.CARD_ID_LENGTH)
                return false;

            if (m_CardHolder == null)
                return false;

            return true;
        }

        #endregion

        #region INullable Implementation

        public bool IsNull
        {
            get { return m_Null; }
        }

        public static PartnerCard Null
        {
            get
            {
                PartnerCard card = new PartnerCard();
                card.m_Null = true;
                return card;
            }
        }

        #endregion

        #region IEquatable<PartnerCard> Implementation

        /// <summary>
        /// TODO: Description
        /// </summary>
        /// <param name="other">TODO: Description</param>
        /// <returns>TODO: Description</returns>
        public bool Equals(PartnerCard other)
        {
            if (!m_CardID.Equals(other.CardID))
                return false;

            return true;
        }

        #endregion

        #region Private Fields

        private string m_CardID = default(string);
        private User m_CardHolder = null;
        private bool m_Null = false;

        #endregion
    }
}
